<?php


namespace App\Http\Controllers\Api;


use App\Constants\AgreementConstant;
use App\Constants\IntegralLogTypeConstant;
use App\Constants\MemberTaskConstant;
use App\Constants\MiniProgramConstant;
use App\Constants\SignConstant;
use App\Constants\SmsConstant;
use App\Models\Config;
use App\Models\Member;
use App\Models\MemberIntegralLog;
use App\Models\MemberSignLog;
use App\Models\MemberTask;
use App\Models\MemberTaskLog;
use App\Services\IntegralService;
use App\Services\SmsService;
use App\Services\VipService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Validator;

class IntegralController extends Controller
{
    public function index(Request $request)
    {
        $memberId = auth('api')->user()->id;

        $log = MemberSignLog::query()
            ->where('member_id', '=', $memberId)
            ->where('mini_type', '=', $this->getMiniType())
            ->orderByDesc('id')
            ->first();

        $continueDay = 0;

        if ($log) {
            $lastDate = date('Ymd', strtotime($log->created_at));
            if ($lastDate == date('Ymd') || $lastDate == date('Ymd', strtotime('-1 day'))) {
                $continueDay = $log->continue_day;
            }
            $isSign = date('Ymd') == $lastDate;
        }

        $tasks = MemberTask::query()
            ->where('status', '=', true)
            ->where('mini_type', '=', $this->getMiniType())
            ->orderByDesc('sort')
            ->get();

        if ($tasks->count()) {
            $query = MemberTaskLog::query()
                ->where('member_id', '=', $memberId)
                ->where('mini_type', '=', $this->getMiniType());

            foreach ($tasks->pluck('slug') as $slug) {
                $query->selectRaw(sprintf('sum(slug = "%s") as %s', $slug, $slug));
            }

            $ret = $query->whereDate('created_at', '=', date('Y-m-d'))->first()->toArray();

            foreach ($tasks as $task) {
                $task->finish_num = $ret[$task->slug] ?? 0;
            }
        }

        $data = [
            'integral'     => Member::query()->where('id', $memberId)->value('integral'),
            'continue_day' => $continueDay,
            'is_sign'      => $isSign ?? false,
            'config'       => getMiniSettings($this->getMiniType(), SignConstant::GROUP),
            'tasks'        => $tasks,
        ];

        return $this->_success($data);
    }

    public function logs(Request $request)
    {
        $memberId = auth('api')->user()->id;

        $list = MemberIntegralLog::query()
            ->where('member_id', '=', $memberId)
            ->where('mini_type', '=', $this->getMiniType())
            ->select(['content', 'change', 'created_at'])
            ->orderByDesc('id')
            ->paginate();

        return $this->_success([
            'list' => $list->items()
        ]);
    }

    public function exchange(Request $request)
    {
        $memberId = auth('api')->user()->id;

        $data = Validator::make($request->post(), [
            'integral' => 'required|integer|min:1',
            'code'     => 'required',
        ], [
            'integral.required' => '积分不能为空',
            'integral.integer'  => '积分类型错误',
            'integral.min'      => '积分最小为1',
            'code.required'     => '验证码不能为空',
        ])->validate();

        $info = Member::query()->where('id', '=', $memberId)->first(['integral', 'phone']);
        if (!$info->phone) {
            return $this->error('请先绑定手机号');
        }

        if (!SmsService::instance()->check($info->phone, $data['code'], SmsConstant::TPL_TYPE_EXCHANGE_INTEGRAL)) {
            return $this->error('验证码错误');
        }

        $integral = $data['integral'];

        if ($info->integral < $integral) {
            return $this->error('兑换积分余额不足');
        }

        DB::transaction(function () use ($memberId, $integral) {
            app(IntegralService::class)->store($this->getMiniType(), $memberId, -$integral, IntegralLogTypeConstant::TYPE_BY_EXCHANGE, '兑换积分');
        });

        return $this->success('兑换成功');
    }

    public function exchangeVip(Request $request)
    {
        $memberId = auth('api')->user()->id ?? 0;

        if (!$memberId) return $this->error('请先登录', [], 40001, 401);

        $integral = Member::where('id', $memberId)->value('integral') ?: 0;

        $rateInfo = [
            'integral' => 100,
            'day'      => 1,
        ];

        $maxExchangeDay = intval($integral / $rateInfo['integral']);

        if ($request->isMethod('POST')) {
            $day = $request->input('day', 0);
            if ($day <= 0) return $this->error('兑换天数最低为1');

            if ($day > $maxExchangeDay) return $this->error('兑换天数不能超过' . $maxExchangeDay . '天');

            app(VipService::class)->exchangeVip($memberId, $day, $day * $rateInfo['integral']);

            return $this->success('兑换成功');
        }

        return $this->_success(compact('integral', 'rateInfo', 'maxExchangeDay'));
    }

    public function info(Request $request)
    {
        $miniType = $this->getMiniType();
        $memberId = auth('api')->user()->id ?? 0;

        if (!$memberId) return $this->error('请先登录', [], 40001, 401);

        $integral = Member::query()->where('id', $memberId)->value('integral');
        $rule = Config::query()
            ->where(['name' => AgreementConstant::TYPE_BY_INTEGRAL, 'mini_type' => $miniType])
            ->select(['name_title', 'content'])
            ->first();

        $exchangeSwitch = getMiniSettings($miniType, MiniProgramConstant::GROUP, MiniProgramConstant::EXCHANGE_INTEGRAL_SWITCH);

        return $this->_success(compact('integral', 'rule', 'exchangeSwitch'));
    }
}
